package com.study.web.context;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.study.common.security.KeyRepository;
import com.study.common.security.RSAUtils;
import com.study.common.security.URLutil;
import com.study.common.utils.RequestUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.study.common.page.PageParam;


public class SpringMVCActionSupport {
	
	/**
	 * 共享空List实例,用于空实例
	 */
	public static final List<Object> EMPTY_LIST = new ArrayList<Object>();
	
	/**
	 * 共享空Map实例,用于空实例
	 */
	public static final Map<Object,Object> EMPTY_MAP = new HashMap<Object,Object>(0);
	
	/**
	 * 获取request对象
	 * @return
	 */
	public HttpServletRequest getHttpRequest(){
		return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); 
	}
	
	/**
	 * 获取String类型参数 无值则返回null
	 * @param key
	 * @return
	 */
	public String getString(String key){
		return getHttpRequest().getParameter(key);
	}
	/**
	 * 获取String类型参数  无值则返回"" .
	 * @param key
	 * @return
	 */
	public String getString_UrlDecode_GBK(String key) {
		try {
			return new String(getString(key.toString()).getBytes("GBK"), "UTF-8");
		} catch (Exception e) {
			return "";
		}

	}
	/**
	 * 根据参数名从HttpRequest中获取String类型的参数值，无值则返回"" .
	 * 
	 * @param key
	 *            .
	 * @return String .
	 */
	public String getString_UrlDecode_UTF8(String key) {
		try {
			return URLDecoder.decode(this.getString(key), "UTF-8");
		} catch (Exception e) {
			return "";
		}

	}
	/**
	 * 根据参数名从HttpRequest中获取String[] 类型的参数值 有 返回字符串数组 无 返回null;
	 * 
	 * @param key
	 *            .
	 * @return String[] or null .
	 */
	public String[] getStringArr(String key) {
		return getHttpRequest().getParameterValues(key);
	}
	/**
	 * 获取分页参数，包含当前页、每页记录数.
	 * 
	 * @return PageParam .
	 */
	public PageParam getPageParam() {
		return new PageParam(getPageNum(), getNumPerPage());
	}
	/**
	 * 获取当前页
	 * 如果没有值则默认返回1.
	 * 
	 * @author WuShuicheng.
	 */
	private int getPageNum() {
		// 当前页数
		String pageNumStr = getHttpRequest().getParameter("pageNum");
		int pageNum = 1;
		if (StringUtils.isNotBlank(pageNumStr)) {
			pageNum = Integer.valueOf(pageNumStr);
		}
		return pageNum;
	}
	/**
	 * 获取每页记录数
	 * 如果没有值则默认返回10.
	 * 
	 */
	private int getNumPerPage() {
		String numPerPageStr = getHttpRequest().getParameter("numPerPage");
		int numPerPage = 10;
		if (StringUtils.isNotBlank(numPerPageStr)) {
			numPerPage = Integer.parseInt(numPerPageStr);
		}
		return numPerPage;
	}
	/**
	 * 根据参数名从HttpRequest中获取Double类型的参数值，无值则返回null .
	 * 
	 * @param key
	 *            .
	 * @return DoubleValue or null .
	 */
	public Double getDouble(String key) {
		String value = getHttpRequest().getParameter(key);
		if (StringUtils.isNotBlank(value)) {
			return Double.parseDouble(value);
		}
		return null;
	}

	/**
	 * 根据参数名从HttpRequest中获取Integer类型的参数值，无值则返回null .
	 * 
	 * @param key
	 *            .
	 * @return IntegerValue or null .
	 */
	public Integer getInteger(String key) {
		String value = getHttpRequest().getParameter(key);
		if (StringUtils.isNotBlank(value)) {
			return Integer.parseInt(value);
		}
		return null;
	}

	/**
	 * 根据参数名从HttpRequest中获取Long类型的参数值，无值则返回null .
	 * 
	 * @param key
	 *            .
	 * @return LongValue or null .
	 */
	public Long getLong(String key) {
		String value = getHttpRequest().getParameter(key);
		if (StringUtils.isNotBlank(value)) {
			return Long.parseLong(value);
		}
		return null;
	}

    //前端RSA 加密开始 ------------------------ start 20190530

    protected Map<String, Object> session=new HashMap<String,Object>();
    private final static String MPARA="MPARA";
    private final static String MTT="MTT";
    private final static String MKK="MKK";
    private final static String KeyRepository="KeyRepository";

    /**
     * 检查KeyRepository是否有效
     *<pre> </pre>
     * @return true-有效   / false-过期
     */
    private boolean chKeyRepositoryForTrue(){
        KeyRepository keyR = (KeyRepository)session.get(KeyRepository);
        //session内存储密钥对, 非空, 且未超过3分钟 即有效密钥对
        if(keyR==null || System.currentTimeMillis() - keyR.getGenerateDate().getTime() > 180*1000){
            return false;
        }else{
            return true;
        }
    }

    /**
     * 页面
     * 初始化用户密钥
     * <pre> </pre>
     *
     * @return 最新密钥
     * @throws Exception 抛出密钥生成失败
     */
    protected KeyRepository initRSAMEbyUser(HttpServletRequest request) throws Exception {
        KeyRepository keyR = (KeyRepository) session.get(KeyRepository);
        if (chKeyRepositoryForTrue() == false) {
            keyR = RSAUtils.getKeys();
            session.put(KeyRepository, keyR);
        }
        // 公钥信息保存在页面，用于加密
        request.setAttribute("EE", keyR.getExponent());
        request.setAttribute("MM", keyR.getModulus());
        return keyR;
    }

    /**
     * 从MPARA参数解析加密后的 ,\ 单次验证解码 重复解码将视为重复请求而拒绝
     * 请勿重复调用
     *<pre> </pre>
     * @return 解析后的参数, 不为null, 出现异常将返回 空但不为null
     * @throws Exception
     */
    protected Map<String, String[]> decryptRSAMEbyUserSafety(HttpServletRequest request) throws Exception {
        String parameterMi = paramString(MPARA,request);
        KeyRepository keyR = (KeyRepository) session.get(KeyRepository);
        String parameterMing = RSAUtils.decryptRSAforJS(parameterMi, keyR);
        if (keyR == null || parameterMing == null || parameterMing.isEmpty()) {
            throw new RuntimeException("解码失败");
        }
        parameterMing = URLDecoder.decode(parameterMing, "UTF-8");// 前端使用url中文转码,
        // a=中文&b=中文
        if (RequestUtil.isDeniedAll(parameterMing)) {
            throw new RuntimeException("存在非法字符");
        }

        Map<String, String[]> map = new HashMap<String, String[]>();
        URLutil.parseParameters(map, parameterMing, "UTF-8");

        String mtt = RequestUtil.paraToFirst(map.get(MTT));
        String mtt_se = Long.toString(keyR.getGenerateDate().getTime());
        if (mtt == null || mtt.isEmpty() || !mtt.equals(mtt_se)) {
            throw new RuntimeException("用户密钥过期");// 时间戳--几率被猜出
        }

        String mk = RequestUtil.paraToFirst(map.get(MKK));
        String mk_se = keyR.getUk();
        if (mk == null || mk.isEmpty() || !mk.equals(mk_se)) {
            throw new RuntimeException("用户重复请求");//
        }
        keyR.setUk(null);// 关键 单次验证后将清除uk标示
        return map;
    }

    protected String paramString(String str,HttpServletRequest request){
        return RequestUtil.isNull(request.getParameter(str));
    }

    //前端RSA 加密开始 ------------------------ end
}
